package com.jyw.framework.interceptor;

import com.jyw.common.exception.ServiceException;
import com.jyw.common.filter.RepeatedlyRequestWrapper;
import com.jyw.common.utils.SecurityUtils;
import com.jyw.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.stream.Collectors;

/**
 * 日志拦截器
 *
 * @author 沈峻
 */
@Component
@Slf4j
public class LoggingInterceptor implements HandlerInterceptor {
    /**
     * 日志记录时间日志
     */
    private final static String LOG_TIME_FIELD = "loggingInterceptor_request_time";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求进入控制器之前执行的逻辑
        // 检查是否是文件上传请求，如果是则不处理
        //设置进入接口时间
        request.setAttribute(LOG_TIME_FIELD, System.currentTimeMillis());
        if (!isMultipartRequest(request)) {
            // 获取请求参数
            String queryString = request.getQueryString();
            Long userId = null;
            try {
                userId = SecurityUtils.getUserId();
            } catch (ServiceException e) {
                //没有获取到用户id
            }
            String body = null;
            if(StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)){
                request = new RepeatedlyRequestWrapper(request,response);
                body = readRequestBody(request,response);
            }
            // 可以将queryString记录到日志中
            log.info("请求地址:{},请求用户:{},请求参数:{},请求内容:{}", request.getRequestURI(), userId, queryString, body);
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("请求地址:{},接口请求耗时:{}ms", request.getRequestURI(), System.currentTimeMillis() - (long) request.getAttribute(LOG_TIME_FIELD));
    }

    /**
     * 检查是否是文件上传请求
     *
     * @param request
     * @return
     */
    private boolean isMultipartRequest(HttpServletRequest request) {
        String contentType = request.getContentType();
        return contentType != null && contentType.toLowerCase().startsWith("multipart/");
    }

    /**
     * body内容读取
     *
     * @param request
     * @return
     * @throws IOException
     */
    private String readRequestBody(HttpServletRequest request,HttpServletResponse response) throws IOException {
        try (BufferedReader reader = request.getReader()) {
            return reader.lines().collect(Collectors.joining(System.lineSeparator()));
        }
    }
}
